package com.timerecording.service.login;

import com.alibaba.fastjson.JSON;
import com.timerecording.Enum.UserTypeEnum;
import com.timerecording.common.securityprotect.SecurityPasswordService;
import com.timerecording.dao.login.LoginDao;
import com.timerecording.domain.entity.LoginEntity;
import com.timerecording.domain.entity.UserEntity;
import com.timerecording.domain.vo.login.CaptchaVO;
import com.timerecording.service.LoginLog.LoginLogResultEnum;
import com.timerecording.service.LoginLog.LoginLogService;
import com.timerecording.service.LoginLog.domain.LoginLogEntity;
import com.timerecording.service.login.captcha.CaptchaService;
import com.timerecording.util.JwtUtils;
import com.timerecording.util.ResponseCodeConst;
import com.timerecording.util.ResponseDTO;
import com.timerecording.util.SmartIpUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.flink.fs.s3presto.shaded.com.facebook.presto.hadoop.$internal.org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author smz41
 * @description: TODO
 * @date 2024/4/10
 */
@Service
public class LoginService {

    public static final String salt = "record!@#$%";

    @Resource
    private CaptchaService captchaService;


    @Resource
    private LoginLogService loginLogService;


    @Resource
    private SecurityPasswordService securityPasswordService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    @Resource
    private LoginDao loginDao;

    /** 获取验证码
     * @description: TODO
     * @author smz
     * @version 1.0
     * @date 2025/1/26
     */

    public ResponseDTO<CaptchaVO> getCaptcha() {
        return ResponseDTO.ok(captchaService.generateCaptcha());
    }


    /** 保存登录日志
     * @description: TODO
     * @author smz
     * @version 1.0
     * @date 2025/1/27
     */

    private void saveLoginLog(String ip, String userAgent, String remark, LoginLogResultEnum result){


        LoginLogEntity login = LoginLogEntity.builder()
                //.userId(employeeEntity.getEmployeeId())
                .userType(UserTypeEnum.ADMIN_EMPLOYEE.getValue())
                //.userName(employeeEntity.getActualName())
                .userAgent(userAgent)
                .loginIp(ip)
                .loginIpRegion(SmartIpUtil.getRegion(ip))
                .remark(remark)
                .loginResult(result.getValue   ())
                .createTime(LocalDateTime.now())
                .build();
        loginLogService.log(login);
    }


    /** 重置密码
     * @description: TODO
     * @author smz
     * @version 1.0
     * @date 2025/1/27
     */

    public ResponseDTO<String> resetPassword(Long employeeId) {
        String password = securityPasswordService.randomPassword();
        loginDao.updatePassword(employeeId,SecurityPasswordService.getEncryptPwd(password));
        return ResponseDTO.ok(password);
    }

    /**  登录
     * @description: TODO
     * @author smz
     * @version 1.0
     * @date 2025/7/21
     */

    public ResponseDTO login(LoginEntity loginEntity) {
        /* todo
        * 参数校验是否合法
        * 根据用户名和密码去user表中查询  是否存在
        * 如果不存在  登陆失败
        * 如果存在  使用jwt生成token  返回给前端
        * token放入redis中，redis token：user信息  设置过期时间
        * （登录认证的时候 先认证token字符串是否合法，去redis认证是否存在）
        *  */
        String loginName = loginEntity.getLoginName();
        String loginPwd = loginEntity.getLoginPwd();
        if (StringUtils.isBlank(loginName) || StringUtils.isBlank(loginPwd)) {
            return ResponseDTO.wrapMsg(ResponseCodeConst.Name_OR_PWD_NOT_EXIST, "用户名或者密码不存在");

        }

        //密码是加密的
        //uuid会生成三十二位数和四位“—”，是随机唯一的，将四位“—”去掉获取到三十二位的盐值
        //String salt = UUID.randomUUID().toString().replace("-","");
        //使用HD5加密，生成加密后的密码
        loginPwd = DigestUtils.md5Hex(loginPwd+salt);

        System.out.println("加密的密码 = " + loginPwd);

        //验证用户是否存在  根据当前的用户名和密码查询t_user中是否存在该用户
        UserEntity userEntity = loginDao.findUser(loginName,loginPwd);
        Optional<UserEntity> optional = Optional.ofNullable(userEntity);
        if (!optional.isPresent()) {
            // 实体对象为null
            return ResponseDTO.wrapMsg(ResponseCodeConst.NOT_EXISTS,"用户不存在");
        }

        String token = JwtUtils.createToken(userEntity.getUserId());

        System.out.println("token = " + token);
        //将查询到的实体类转成String类型
        String s = JSON.toJSONString(userEntity);
        //存入字符串类型
        redisTemplate.opsForValue().set("TOKEN"+token,s,8, TimeUnit.HOURS);  //过期时间设置八小时
        return ResponseDTO.succData(token);
    }


    /**
     * @description: TODO
     * @author smz
     * @version 1.0
     * @date 2025/7/25
     */

    public UserEntity checkToken(String token){
        if (StringUtils.isBlank(token)){
            return null;
        }
        Map<String,Object>  stringObjectMap = JwtUtils.checkToken(token);

        if (stringObjectMap == null){
            return null;

        }

        String userJson = redisTemplate.opsForValue().get("TOKEN" + token);
        if (StringUtils.isBlank(userJson)){
            return null;
        }
        //将userJson解析为user对象
        UserEntity userEntity = JSON.parseObject(userJson, UserEntity.class);
        return userEntity;
    }


    /** 删除redis中的token
     * @description: TODO
     * @author smz
     * @version 1.0
     * @date 2025/7/26
     */

    public void loginout(String token) {
        redisTemplate.delete("TOKEN"+token);
    }
}
